package com.movisol.messengerprofileservice.helpers;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;

import com.movisol.messengerprofileservice.data.Friend;
import com.movisol.messengerprofileservice.data.Friends;
import com.movisol.messengerprofileservice.data.UserProfile;
import com.movisol.messengerprofileservice.exceptions.ProfileServiceWebFault;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.XStreamException;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;

public class MessengerProfileHelper {

	private final static String FRIENDS_CLASS = "Friends";
	private final static String FRIEND_CLASS = "Friend";
	private final static String USER_PROFILE_CLASS = "UserProfile";
	private final static String PROFILE_SERVICE_WEBFAULT_CLASS = "ProfileServiceWebFault";
	
	//Restrict the instantiation of the class
	private MessengerProfileHelper()
	{}

	public static List<Object> parseXMLprofileToObject(String xmlResource) {

		XStream xstream = new XStream();
		UserProfile userProfile = null;
		ProfileServiceWebFault profileSwF = null;
		List<Object> list = new ArrayList<Object>();

		try {
			xstream.alias(FRIENDS_CLASS, Friends.class);
			xstream.alias(FRIEND_CLASS, Friend.class);
			xstream.alias(USER_PROFILE_CLASS, UserProfile.class);
			
			userProfile = (UserProfile) xstream.fromXML(xmlResource);
			//Resets the signature to the original one, not the retrieved by the server answer
//			String signature = MessengerHelper.generateSignature(context, HelperUtils.getDeviceId(context)+HelperUtils.getConfigParam("ProfileSecretPhrase", context));
//			userProfile.setSignature(signature);
		} catch (CannotResolveClassException e) {

			//TODO show error message
			
			xstream.alias(PROFILE_SERVICE_WEBFAULT_CLASS, ProfileServiceWebFault.class);
			profileSwF = (ProfileServiceWebFault) xstream.fromXML(xmlResource);
		}
		
		list.add(userProfile);
		list.add(profileSwF);
		
		return list;
	}

	public static List<Object> parseXMLfriendsToObject(String userFriends) {

		XStream xstream = new XStream();
		Friends friends = null;
		ProfileServiceWebFault profileSwF = null;
		List<Object> list = new ArrayList<Object>();
		
		try {
			xstream.alias(FRIENDS_CLASS, Friends.class);
			xstream.alias(FRIEND_CLASS, Friend.class);
			xstream.alias(USER_PROFILE_CLASS, UserProfile.class);
			
			friends = (Friends) xstream.fromXML(userFriends);

		} catch (CannotResolveClassException e) {

			//TODO show error message
			
			xstream.alias(PROFILE_SERVICE_WEBFAULT_CLASS, ProfileServiceWebFault.class);
			profileSwF = (ProfileServiceWebFault) xstream.fromXML(userFriends);
		}
		
		list.add(friends);
		list.add(profileSwF);
		
		return list;
	}
	
	public static String parseFriendsToXML(Friends friends)
	{
		XStream xstream = new XStream();
		
		xstream.alias(FRIENDS_CLASS, Friends.class);
		xstream.alias(FRIEND_CLASS, Friend.class);
		xstream.alias(USER_PROFILE_CLASS, UserProfile.class);
		
		String friendsInXML = xstream.toXML(friends);
		
		return friendsInXML;
		
	}

	public static String generateSignature(String signature) {
		
		MessageDigest digest;
		try {
		    digest = MessageDigest.getInstance("MD5");
		    digest.reset();
		    digest.update(signature.getBytes());
		    byte[] a = digest.digest();
		    int len = a.length;
		    StringBuilder sb = new StringBuilder(len << 1);
		    for (int i = 0; i < len; i++) {
		        sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
		        sb.append(Character.forDigit(a[i] & 0x0f, 16));
		    }
		    return sb.toString().toUpperCase();
		}
		catch (NoSuchAlgorithmException e) 
		{
			e.printStackTrace(); 
		}
		
		return null;
	}
	


	public static String getStringGender(Integer gender) {
		
		switch(gender)
		{
		case 1:
			return "Female";
		case 2:
			return "Male";
		}
		
		return "<NOT SET>";
		
	}
	
	public static String encodeBase64(String path)
	{

//		Drawable d = new BitmapDrawable();

//		return Base64.encodeToString(input, Base64.DEFAULT);
		return "";
	}
	
//	public static String getContactName(UserProfile userProfile)
//	{
//		if(userProfile.getNickName() != null && !userProfile.getNickName().trim().equals(""))
//		{
//			return userProfile.getNickName();
//		}
//		else
//		{
//			return userProfile.getEmail().substring(0, userProfile.getEmail().indexOf("@"));
//		}
//
//	}
	
	public static boolean validateEmail(String email)
	{
		
		final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
											"[a-zA-Z0-9+._%-+]{1,256}" +
											"@" +
											"[a-zA-Z0-9][a-zA-Z0-9-]{0,64}" +
											"(" +
											"." +
											"[a-zA-Z0-9][a-zA-Z0-9-]{0,25}" +
											")+"
											);
		
		
		return EMAIL_ADDRESS_PATTERN.matcher(email).matches();
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List<Friend> filterFriends(List<Friend> friendList, int friendStatus)
	{
		ArrayList list = new ArrayList();
		
		for(Friend friend : friendList)
		{
			if(friend.getFriendStatusId() == friendStatus)
				list.add(friend);
		}
		
		Comparator<Friend> comparator = new Comparator<Friend>() {

			@Override
			public int compare(Friend object1, Friend object2) {
				return object1.getUserProfile().getCalculatedNickName().toLowerCase().compareTo(object2.getUserProfile().getCalculatedNickName().toLowerCase());
			}
		};
		
		Collections.sort(list, comparator);
		
		return list;
	}
	
	public static boolean isFriendAlreadyAdded(String email, List<Friend> friendList) {

		for(Friend friend : friendList)
			if(friend.getUserProfile().getEmail().equalsIgnoreCase(email))
				return true;

			return false;
	}

	public static Friend findContactInFriends(String userId, Friends friends) {

		for(Friend friend : friends.getFriendList())
		{
			if(friend.getUserProfile().getUserId().equalsIgnoreCase(userId))
				return friend;
		}
		
		return null;
	}



	public static String parseUserProfileToXML(UserProfile profileData) {
		XStream xstream = new XStream();
		String xml = null;
		
		try {
			xstream.alias(USER_PROFILE_CLASS, UserProfile.class);
			xml =  xstream.toXML(profileData);

		} catch (CannotResolveClassException e) {
			return null;
		} catch (XStreamException e) {
			return null;
		}

		
		return xml;
	}
	
	public static List<Object> parsePushNotificationResponseToBoolean(String response) {

		XStream xstream = new XStream();
		List<Object> list = new ArrayList<Object>();
		Boolean pushOk = null;
		try {
			xstream.alias(FRIENDS_CLASS, Boolean.class);
			pushOk = (Boolean) xstream.fromXML(response);

		} catch (CannotResolveClassException e) {
			pushOk = false;
		}
		
		list.add(pushOk);
		
		return list;
	}

}
